var EpgLayout=function(name,links){
	this.name = name;
	this.current = null;
	if(links.length>0){
	  this.current = links[0];
	}
	this.links = links;
	for(var i=0;i<this.links.length;i++){
		var alink = links[i];
		alink["layout"] = name;
	}
	this.findLink = function(id){
		if(id && id == null && id == '') return null;
		 for(var i =0;i<this.links.length;i++){
		 	if(id == this.links[i].id){
		 		return this.links[i];
		 	}
		 }
	},
	this.setCurrent = function(idx){
		this.current = this.links[idx];
	}
};

var EpgPage=function(opts){
	this.opts = opts;
	this.currentLink = null;
	this.layouts = new Array(); 
	this.widgets = new Array();
	this.plugins = new Array();
	this.customKeypress = null;
	this.currentLayout = null;
	this.keyEvent = null;
	this.currentWidget = null;
	
	this.addPlugin = function(plugin){
	  this.plugins.push(plugin);
	}
	
	this.callPlugin = function(link,widget){
		for(i=0;i<this.plugins.length;i++){
			try{
			    var plugin = this.plugins[i];
			    plugin.call(this,link,widget);
			}catch(e){
				
			}
		}
	}
	
	this.addWidget=function(widget){
		this.widgets.push(widget);
	}
	
	this.addLayout =function(name,links){
		
		var layout  = new EpgLayout(name,links);
		if(name=="default"){
			this.currentLayout = layout;
		}
		this.layouts.push(layout);
	}
	this.findWidget=function(id){
		for(var i =0;i< this.widgets.length;i++){
			var idx = this.widgets[i].index(id);
			if(idx>-1){
				return this.widgets[i];
			}
		}
		return null;
	}
	this.init=function(id,keyhandle){
		var self = this;
		if(keyhandle){
			this.customKeypress = keyhandle;
		}else{
			this.customKeypress = document.onkeypress;
		}
		document.onkeypress =function(e){
			self.keypress(e);
		};
		var link= this.findLink(id);
		if(! link){
			link = this.layouts[0].links[0];
		}
		this.switchFocus(link);
		log("focus");
	}
	this.keypress = function(evt){
			log("event");
			if(this.currentLink== null){
				this.curentLink = this.currentLayout.links[0];
			}
			evt = evt ? evt : window.event;
		  	var keyCode = evt.which ? evt.which : evt.keyCode;
		  	log("keycode:"+keyCode);
			keyCode = parseInt(keyCode);
			switch(keyCode){
				case KEY_ENUM.KEY_1:
					window.location.href = window.location.href;
					return;
				case KEY_ENUM.KEY_0:
					$("#msgbox").html("");
					return;
			    case 113:
			    	keyCode = KEY_ENUM.KEY_BACK;
			    	break;
				case KEY_ENUM.KEY_D:
						keyCode = KEY_ENUM.KEY_DOWN;
						break;
				case KEY_ENUM.KEY_U:
						keyCode = KEY_ENUM.KEY_UP;
						break;
				case KEY_ENUM.KEY_L:
					keyCode = KEY_ENUM.KEY_LEFT;
					break;
				case KEY_ENUM.KEY_R:
					keyCode = KEY_ENUM.KEY_RIGHT;
					break;
			}
			var result = false;
			this.keyEvent = {keyCode:keyCode,which:keyCode , target:this.currentLink};
			if(this.currentLink.onkeypress){
				result = eval(this.currentLink.onkeypress);
				log("link:"+this.currentLink.id);
				if(result){
					return ;
				}
			}
			var widget  =this.findWidget(this.currentLink.id)
			if(widget ){
				if(widget.onkeypress) {
					log("widget:"+this.currentLink.id);
						result = widget.onkeypress(this.keyEvent);
						if(result){
							return ;
						}
				}
			}
			if(this.customKeypress){
				result = this.customKeypress({which:keyCode ,target:this.currentLink})
				log("link-c:"+this.currentLink.id);
				if(result==true){
					return ;
				}
			}
			log("af-widget:"+this.currentLink.id);
			var next = null;
			var defNext = null;
			switch(keyCode){				
			    case KEY_ENUM.KEY_BACK:
			    	if(this.currentLayout.name!='default'){
			    		this.switchLayout("default");
			    	}else{
			    		EPG.gotoPage(this.opts.backUrl);
			    	}
			    	break;
				case KEY_ENUM.KEY_LEFT:
					defNext = this.currentLink.direction.leftId;
					next = this.findNextLink(defNext, KEY_ENUM.KEY_LEFT);
					break;
				case KEY_ENUM.KEY_RIGHT:
					defNext = this.currentLink.direction.rightId;
					next = this.findNextLink(defNext,KEY_ENUM.KEY_RIGHT);
				break;
				case KEY_ENUM.KEY_DOWN:
					defNext = this.currentLink.direction.downId;
					next = this.findNextLink(defNext,KEY_ENUM.KEY_DOWN);
					break;
				case KEY_ENUM.KEY_UP:
					defNext = this.currentLink.direction.upId;
					next = this.findNextLink(defNext,KEY_ENUM.KEY_UP);
					break;
				case KEY_ENUM.KEY_OK:
					this.callPlugin(this.currentLink,widget);
					this.gotoPage(this.currentLink);
					break;
			}
			//log("keypress:"+this.currentLink.id);
			//log("next："+next.id);
			if(next != null){
				this.switchFocus(next);
			} else {
				if(defNext != null) {
					var aCur = this.currentLink;
					if(this.focusWidget(defNext)){
						this.blur(this.currentLink);
						this.blurWidget(defNext.id);
					}
				}
			}
			//evt.stopPropagation();
			//evt.preventDefault();
			
			return false;
	}
	this.findNextLink=function(id,key){
		var link = this.findLink(id);
		if(link==null) return null;
		if(!link.disable){
			return link;
		}else{
			switch(key){
			case KEY_ENUM.KEY_LEFT:
				if(link.direction.leftId){
					return this.findNextLink(link.direction.leftId,key);
				}
				break;
			case KEY_ENUM.KEY_RIGHT:
				if(link.direction.rightId){
				  return  this.findNextLink(link.direction.rightId,key);
				}		
				break;
			case KEY_ENUM.KEY_DOWN:
				if(link.direction.downId){
				 return  this.findNextLink(link.direction.downId,key);
				}
				break;
			case KEY_ENUM.KEY_UP:
				if(link.direction.upId){
					 return  this.findNextLink(link.direction.upId,key);
				}
				break;
			}
		}
		return null;
	}
	this.$=function(id){
		return document.getElementById(id);
	}
	this.cursorEffect=function(link){
		if(link.focusCursor){
			var img = $("#"+link.id+"_cursor_img");
			var offset = img.offset();
			$("#focusCursor").css("background-image","url('"+link.focusCursor+"')");
			$("#focusCursor").css("width",img.css("width"));
			$("#focusCursor").css("height",img.css("height"));
			$("#focusCursor").css("top",offset.top+"px");
			$("#focusCursor").css("left",offset.left+"px");
		}
	}
	this.effect=function(obj){
	
		if(! obj.effects) return ;
		for(var i=0;i<obj.effects.length;i++){
			var item = obj.effects[i];
			if(item.effect=="marquee"){
				var a = new EpgEffect(item.id)
				a.marquee();
			}else if(item.effect.indexOf("css(")==0){
				var pattern =/\'(.*?)\'/;
				css = pattern.exec(item.effect);
				var a = new EpgEffect(item.id)
				a.addClass(css[1]);
			}
		}
	}
	this.uneffect=function(obj){
		if(obj.focusCursor){
			this.$(obj.id+"_cursor_img").src = "/epg/images/dot.gif";
		}
		if(! obj.effects) return ;
		for(var i=0;i<obj.effects.length;i++){
			var item = obj.effects[i];
			if(item.effect=="marquee"){
				var a = new EpgEffect(item.id)
				a.marqueeStop();
			}else if(item.effect.indexOf("css(")==0){
				var pattern =/\'(.*?)\'/;
				css = pattern.exec(item.effect);
				var a = new EpgEffect(item.id)
				a.removeClass(css[1]);
			}
		}
	}
	this.focusWidget=function(id){
		widget = this.findWidget(id);
		if(widget!=null){
			if(widget!=this.currentWidget){
				if(widget.focus){
					var flag = widget.focus(id);
					if(flag) {
						this.currentWidget = widget;
					}
					return flag;
				}
			}
		}
		return false;
	}
	this.blurWidget=function(id){
		if(this.currentLink==null){
			return false;
		}
		var result = false;
		widget = this.findWidget(id);
		if(widget!=null && this.currentWidget!=null){
			if(widget!=this.currentWidget){
				if(this.currentWidget.blur){
					result = this.currentWidget.blur(this.currentLink.id);
				}
			}
		}
		return result;
	}	
	this.switchFocus=function(obj){
		if(typeof(obj)=="string"){
			obj = this.findLink(obj);
		}
		if(obj!=null){
			var widget = this.findWidget(obj.id);
			if(obj.disable){
				return ;
			}
			if(this.currentLink){
				this.blur(this.currentLink);
				this.blurWidget(obj.id);
			}
			if(!this.focusWidget(obj.id)){
				this.focus(obj);
			}
			this.currentWidget = widget;
		}
		log("focused:"+obj);
	}
	this.focus=function(obj){
		if(typeof(obj)=="string"){
			obj = this.findLink(obj);
		}
		if(obj!=null){
			if(obj.disable){
				return ;
			}
		}
		if(this.currentLayout.name != obj.layout){
			this.switchLayout(obj.layout,obj.id);
		}
		this.currentLayout.current = obj;
		this.currentLink= obj;
		this.cursorEffect(obj);
		this.effect(obj);
		if(obj!=null && obj.onfocus!=null && obj.onfocus!=""){
			eval(obj.onfocus);
		}
	}
	this.blur=function(obj){
		if(! obj) return ;
		if(typeof(obj)=="string"){
			obj = this.findLink(obj);
		}
		this.uneffect(obj);
		if(obj!=null && obj.blur!=null && obj.blur!=""){
			eval(obj.blur);
		}
		
	}

	
	this.findLink=function(id){
		for(var i=0;i<this.layouts.length;i++){
			var alink = this.layouts[i].findLink(id);
			if(alink){
				return alink;
			}
		}
		return null;
	}
	this.reset = function(id){
		var self = this;
		document.onkeypress =function(e){
			self.keypress(e);
		};
		if(id){
			var aLink= this.findLink(id);
			this.switchFocus(aLink);
		}
		log("focus");
	}
	this.gotoPage=function(id){
		var link = this.currentLink;
		if(id){
			if(typeof(id)=="string"){
				link = this.findLink(id);
			}else{
				link = id;
			}
		}
	    if(link!=null){
	    	if(link.href.indexOf('javascript:')==0){
	    		var func = link.href.substring(11,this.currentLink.href.length);
	    		eval(func);
	    	}else{
	    		EPG.gotoPage(link.href,link.id);
	    	}
	    }
	}
	this.switchLayout = function(name,focusId){
		if(this.currentLayout.name!="default" && this.currentLayout.name!=name){
			$("#"+this.currentLayout.name).hide();
		}
		if(name != "default"){
			var defLayout = this.findLayout("default");
			if(defLayout&&defLayout.links.length>1){
				defLayout.current = defLayout.links[1];
			}
		}
		var alayout = this.findLayout(name);
		if(null != alayout){
			this.currentLayout = alayout;
			$("#"+name).show();
			if(focusId){
				var alink = this.currentLayout.findLink(focusId);		
				this.switchFocus(alink);
			}else{
				this.switchFocus(this.currentLayout.current);
			}
		}
		
	}
	this.findLayout = function(name){
		for(var i=0;i<this.layouts.length;i++){
			if(this.layouts[i].name == name){
				return this.layouts[i];
			}
		}
		return null;
	}
	this.destroy = function(){
		for(var i=0;i<this.widgets.length;i++){
			this.widgets[i].destroy();
		}
	}
}